package main

import ("fmt"
	"io"
	"log"
)

func main()  {
	//fmt.Println("main call def :",def(1))
	//fmt.Println("main call def1 :",def1(1))
	//tracetest1()
	//a()
	//record("record now")
	def2(1)
}

func def(a int) int  {

	defer fmt.Println("defer: ",a)
	fmt.Println("defer next line: ",a)
	return 0
}
//多个 defer 行为被注册时，它们会以逆序执行（类似栈，即后进先出）
func def1(a int) int  {
	for a:=0;a<10;a++ {
		defer fmt.Println("defer in for : ",a)
	}
	defer fmt.Println("defer: ",a)
	fmt.Println("defer next line: ",a)
	return 0
}
//闭包引用传递
func def2(a int) int  {
	for a:=0;a<10;a++ {
		defer func() {
			fmt.Println("闭包，引用传递: ",a)
		}()
	}
	return 0
}

//代码追踪
func trace(s string)  {
	fmt.Println("enter: ",s)
}

func untrace(s string)  {
	fmt.Println("out: ",s)
}
func tracetest() string {
	trace("tracetest")
	defer untrace("tracetest")
	fmt.Println("end")
	return ""
}
func simtrace(s string)string  {
	fmt.Println("enter simtrace: ",s)
	return s
}

func unsimtrace(s string)  {
	fmt.Println("out simtrace: ",s)
}
//放在第一行，保证一进入方法即输出，外层的 unsimtrace() 方法才是真正的 defer 属性，unsimtrace里调用的方法出在初始化 defer 时即执行
func tracetest1() string {
	defer unsimtrace(simtrace("tracetest1"))
	fmt.Println("end")
	return ""
}

//使用 defer 语句来记录函数的参数与返回值
func record(s string)(n int,err error)  {
	defer func() {
		log.Printf("record(%q) = %d %v",s,n,err)
	}()		//最后一个 ()是用来调用匿名方法的
	return 7,io.EOF
}

